Шаг 54 - DispGetParam.

Считывает параметр из структуры DISPPARAMS, проверяя как позиционные, так и именованные параметры, и приводит параметр к заданному типу.

HRESULT DispGetParam
( 
DISPPARAMS FAR* pdispparams, 
unsigned int position, 
VARTYPE vtTarg, 
VARIANT FAR* pvarResult, 
unsigned int FAR* puArgErr 
);

Параметры
pdispparams
Указатель на параметры, переданные IDispatch::Invoke.
position
Позиция параметра в списке аргументов.
DispGetParam начинает с конца массива, так что если position равен 0, то возвращается последний параметр массива.
vtTarg
Тип, к которому следует привести значение параметра.
pvarResult
Указатель на вариант, в который следует поместить параметр.
puArgErr
После возврата указывает на индекс аргумента, вызвавшего ошибку DISP_E_TYPEMISMATCH. Этот указатель возвращается Invoke, чтобы указать позицию вызвавшего ошибку аргумента в DISPPARAMS.

Коды возврата
Из возвращенного HRESULT получают один из следующих кодов возврата:
Код возврата Значение
S_OK Успех.
DISP_E_BADVARTYPE Тип варианта vtTarg не поддерживается.
DISP_E_OVERFLOW Полученный параметр невозможно привести к заданному типу.
DISP_E_PARAMNOTFOUND Параметр, заданный position, не найден.
DISP_E_TYPEMISMATCH Аргумент невозможно привести к заданному типу.
E_INVALIDARG Один из параметров неверен.
E_OUTOFMEMORY He хватает памяти для выполнения операции.

Комментарии
Выходной параметр pvarResult должен быть допустимым вариантом. Текущее содержимое будет освобождено стандартным способом. Содержимое варианта освобождается с помощью VariantFree.
Если Вы используете DispGetParam для получения правой части в операции установки значения свойства, то вторым параметром должен быть DISPID_PROPERTYPUT. Например:

DispGetParam(&dispparams,  DISPID_PROPERTYPUT,  VT_BOOL,  &varResult)

Невозможен доступ к именованным параметрам позиционно, и наоборот.

Пример
В следующем примере DispGetParam используется для установки свойств X и Y:

STDMETHODIMP CPoint::Invoke(
DISPID dispidMember,
REFIID riid,
LCID Icid,
unsigned short wFlags,
DISPPARAMS FAR* pdispparams,
VARIANT FAR* pvarResult,
EXCEPINFO FAR* pExcepInfo,
unsigned int FAR* puArgErr) 

{
unsigned int uArgErr;
HRESULT hresult;
VARIANTARG vargO;
VARIANT varResultDummy;
UNUSED(lcid);
UNUSED(pExcepInfo);
// Проверка wFlags.

if(wFlags & (DISPATCH_METHOD | DISPATCH_PROPERTYGET |
DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))

return ResultFromScode(E_INVALIDARG);

// Данный объект предоставляет только интерфейс "по умолчанию".

if(!IsEqualIID(riid, IID_NULL)) return ResultFromScode(DISP_E_UNKNOWNINTERFACE);

// Упрощает следующий ниже код в том случае, когда 
// вызывающий игнорирует возвращаемое значение.

if(puArgErr == NULL)
puArgErr = &uArgErr; 
if(pvarResult == NULL)
pvarResult = &varResultDummy;
VariantInit(&vargO);

// Исходно предполагаем, что возвращаемого значения нет.

Variantlnit(pvarResult);
switch(dispidMember)
{ 

case IDMEMBER_CPOINT_GETX:
V_VT(pvarResult) = VT_I2;
V_I2(pvarResult) = GetX();
break;

case IDMEMBER_CPOINT_SETX:

hresult = DispGetParam(pdispparams,  0, VT_I2, &vargO,  puArgErr); 
if(hresult != NOERROR) return hresult; 
SetX(V_I2(&vargO)); 
break;

case IDMEMBER_CPOINT_GETY: 
V_VT(pvarResult) = VT_I2; 
V_I2( pvarResult) = GetY(); 
break;

case IDMEMBER_CPOINT_SETY:
hresult = DispGetParam(pdispparams,  0, VT_I2,  &vargO,  puArgErr); 
if(hresult != NOERROR) return hresult; 
SetY(V_I2(&vargO)); 
break;

default:
return ResultFromScode(DISP_E_MEMBERNOTFOUND); 

}

return NOERROR; 
}
Hosted by uCoz